home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 3: The Continuation / 17-Bit_The_Continuation_Disc.iso / amigan / amigan 8 / hack.main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-27  |  11.1 KB  |  459 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* hack.main.c version 1.0.1 - some cosmetic changes */
  3.  
  4. #include <stdio.h>
  5. #include <signal.h>
  6. /* #include <errno.h> */
  7. #include "hack.h"
  8.  
  9. extern char *getlogin();
  10. extern char plname[PL_NSIZ], pl_character[PL_CSIZ];
  11. extern char *getenv();
  12.  
  13. int (*afternmv)();
  14.  
  15. int done1();
  16. int hangup();
  17.  
  18. char safelock[] = "safelock";
  19. xchar locknum;            /* max num of players */
  20. char SAVEF[PL_NSIZ + 22] = "Saved Games/";
  21. char perm[] = "perm";
  22. char *hname;      /* name of the game (argv[0] of call) */
  23. char obuf[BUFSIZ];   /* BUFSIZ is defined in stdio.h */
  24.  
  25. extern char *nomovemsg;
  26. extern long wailmsg;
  27.  
  28. main(argc,argv)
  29. int argc;
  30. char *argv[];
  31. {
  32.    int fd;
  33. #ifdef NEWS
  34.     int nonews = 0;
  35. #endif NEWS
  36.    char *dir;
  37.  
  38.    initterm();
  39. #ifdef AMIGA
  40.    if (argc == 0)
  41.     {
  42.     geticon();
  43.     hname = HACKNAME;
  44.     argc = 1;
  45.     }
  46.    else
  47. #endif
  48.    hname = argv[0];
  49.  
  50.    /*
  51.     * See if we must change directory to the playground.
  52.     * (Perhaps hack runs suid and playground is inaccessible
  53.     *  for the player.)
  54.     * The environment variable HACKDIR is overridden by a
  55.     *  -d command line option.
  56.     */
  57.    if ( (dir = getenv("HACKDIR")) == NULL)
  58.     dir = HACKDIR;
  59.  
  60.    if(argc > 1 && !strncmp(argv[1], "-d", 2)) {
  61.       argc--;
  62.       argv++;
  63.       dir = argv[0]+2;
  64.       if(*dir == '=' || *dir == ':') dir++;
  65.       if(!*dir && argc > 1) {
  66.          argc--;
  67.          argv++;
  68.          dir = argv[0];
  69.       }
  70.       if(!*dir)
  71.             error("Flag -d must be followed by a directory name.");
  72.    }
  73.  
  74.    /*
  75.     * Now we know the directory containing 'record' and
  76.     * may do a prscore().
  77.     */
  78.    if(argc > 1 && !strncmp(argv[1], "-s", 2)) {
  79.       if(dir) chdirx(dir);
  80.       prscore(argc, argv);
  81.       hackexit(0);
  82.    }
  83.  
  84.    /*
  85.     * It seems he really wants to play. Find the creation date of
  86.     * this game so as to avoid restoring outdated savefiles.
  87.     */
  88.    gethdate(hname);
  89.  
  90.    /*
  91.     * We cannot do chdir earlier, otherwise gethdate will fail.
  92.     */
  93.    if(dir) chdirx(dir);
  94.  
  95.    /*
  96.     * Who am i? Perhaps we should use $USER instead?
  97.     */
  98. #ifdef AMIGA
  99.    if (!*plname)
  100. #endif
  101.     (void) strncpy(plname, getlogin(), sizeof(plname)-1);
  102.  
  103.    /*
  104.     * Process options.
  105.     */
  106.     initoptions();
  107.    while(argc > 1 && argv[1][0] == '-'){
  108.       argv++;
  109.       argc--;
  110.       switch(argv[0][1]){
  111. #ifdef WIZARD
  112.       case 'w':
  113.          if(!strcmp(getlogin(), WIZARD))
  114.             wizard = TRUE;
  115.          else myprintf("Sorry.\n");
  116.          break;
  117. #endif WIZARD
  118. #ifdef NEWS
  119.         case 'n':
  120.             flags.nonews = TRUE;
  121.             break;
  122. #endif NEWS
  123.       case 'u':
  124.          if(argv[0][2])
  125.            (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
  126.          else if(argc > 1) {
  127.            argc--;
  128.            argv++;
  129.            (void) strncpy(plname, argv[0], sizeof(plname)-1);
  130.          } else
  131.             myprintf("Player name expected after -u\n");
  132.          break;
  133.       default:
  134.          myprintf("Unknown option: %s\n", *argv);
  135.       }
  136.    }
  137.  
  138.    if(argc > 1)
  139.       locknum = atoi(argv[1]);
  140. #ifdef WIZARD
  141.    if(wizard) (void) strcpy(plname, "wizard"); else
  142. #endif WIZARD
  143.    if(!*plname || !strncmp(plname, "player", 4)) askname();
  144. #ifdef AMIGA
  145.    if (!pl_character[0])
  146. #endif
  147.    plnamesuffix();      /* strip suffix from name */
  148.  
  149.    setbuf(stdout,obuf);
  150.     (void) srand(getpid());
  151.    startup();
  152.    cls();
  153.    (void) signal(SIGHUP, hangup);
  154. #ifdef WIZARD
  155.    if(!wizard) {
  156. #endif WIZARD
  157.       (void) signal(SIGQUIT,SIG_IGN);
  158.       (void) signal(SIGINT,SIG_IGN);
  159.       if(locknum)
  160.          lockcheck();
  161.       else
  162.          (void) strcpy(lock,plname);
  163. #ifdef WIZARD
  164.    } else {
  165.       register char *sfoo;
  166.       (void) strcpy(lock,plname);
  167.       if(sfoo = getenv("MAGIC"))
  168.          while(*sfoo) {
  169.             switch(*sfoo++) {
  170.             case 'n': (void) srand(*sfoo++);
  171.                break;
  172.             }
  173.          }
  174.       if(sfoo = getenv("GENOCIDED")){
  175.          if(*sfoo == '!'){
  176.             extern struct permonst mons[PMONCOUNT];
  177.             extern char genocided[], fut_geno[];
  178.             register struct permonst *pm = mons;
  179.             register char *gp = genocided;
  180.  
  181.             while(pm < mons+CMNUM+2){
  182.                if(!index(sfoo, pm->mlet))
  183.                   *gp++ = pm->mlet;
  184.                pm++;
  185.             }
  186.             *gp = 0;
  187.          } else
  188.             (void) strcpy(genocided, sfoo);
  189.          (void) strcpy(fut_geno, genocided);
  190.       }
  191.    }
  192. #endif WIZARD
  193.    u.uhp = 1;   /* prevent RIP on early quits */
  194.    u.ux = FAR;   /* prevent nscr() */
  195.    (void) strcat(SAVEF,plname);
  196.    if((fd = open(SAVEF,0)) >= 0 &&
  197.       (uptodate(fd) || unlink(SAVEF) == 666)) {
  198.       (void) signal(SIGINT,done1);
  199.       myputs("Restoring old save file...");
  200.       (void) myfflush(stdout);
  201.       dorecover(fd);
  202.       flags.move = 0;
  203.    } else {
  204. #ifdef NEWS
  205.     if(!flags.nonews)
  206.         if((fd = open(NEWS,0)) >= 0)
  207.             outnews(fd);
  208. #endif NEWS
  209.       flags.ident = 1;
  210.       init_objects(0);
  211.       u_init();
  212.       (void) signal(SIGINT,done1);
  213.       glo(1);
  214.       mklev();
  215.       u.ux = xupstair;
  216.       u.uy = yupstair;
  217.       (void) inshop();
  218.       setsee();
  219.       flags.botlx = 1;
  220.       makedog();
  221.       seemons();
  222.       docrt();
  223.       pickup();
  224.       read_engr_at(u.ux,u.uy);   /* superfluous ? */
  225.       flags.move = 1;
  226.       flags.cbreak = ON;
  227.       flags.echo = OFF;
  228.    }
  229.    setftty();
  230. #ifdef TRACK
  231.    initrack();
  232. #endif TRACK
  233.    for(;;) {
  234.       if(flags.move) {
  235. #ifdef TRACK
  236.          settrack();
  237. #endif TRACK
  238.          if(moves%2 == 0 ||
  239.            (!(Fast & ~INTRINSIC) && (!Fast || rn2(3)))) {
  240.             extern struct monst *makemon();
  241.             movemon();
  242.             if(!rn2(70))
  243.                 (void) makemon((struct permonst *)0, 0, 0);
  244.          }
  245.          if(Glib) glibr();
  246.          timeout();
  247.             ++moves;
  248.             if(flags.time) flags.botl = 1;
  249.             if(u.uhp < 1) {
  250.                 pline("You die...");
  251.                 done("died");
  252.                 }
  253.          if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50){
  254.              wailmsg = moves;
  255.              if(u.uhp == 1)
  256.              pline("You hear the wailing of the Banshee...");
  257.              else
  258.              pline("You hear the howling of the CwnAnnwn...");
  259.          }
  260.          if(u.uhp < u.uhpmax) {
  261.             if(u.ulevel > 9) {
  262.                if(Regeneration || !(moves%3)) {
  263.                    flags.botl = 1;
  264.                    u.uhp += rnd((int) u.ulevel-9);
  265.                    if(u.uhp > u.uhpmax)
  266.                   u.uhp = u.uhpmax;
  267.                }
  268.             } else if(Regeneration ||
  269.                (!(moves%(22-u.ulevel*2)))) {
  270.                flags.botl = 1;
  271.                u.uhp++;
  272.             }
  273.          }
  274.          if(Teleportation && !rn2(85)) tele();
  275.          if(Searching && multi >= 0) (void) dosearch();
  276.          gethungry();
  277.          invault();
  278.       }
  279.       if(multi < 0) {
  280.          if(!++multi){
  281.             pline(nomovemsg ? nomovemsg :
  282.                "You can move again.");
  283.             nomovemsg = 0;
  284.             if(afternmv) (*afternmv)();
  285.             afternmv = 0;
  286.          }
  287.       }
  288.       flags.move = 1;
  289.       find_ac();
  290. #ifndef QUEST
  291.       if(!flags.mv || Blind)
  292. #endif QUEST
  293.       {
  294.          seeobjs();
  295.          seemons();
  296.          nscr();
  297.       }
  298.       if(flags.botl || flags.botlx) bot();
  299.       if(multi > 0) {
  300. #ifdef QUEST
  301.          if(flags.run >= 4) finddir();
  302. #endif QUEST
  303.          lookaround();
  304.          if(!multi) {   /* lookaround may clear multi */
  305.             flags.move = 0;
  306.             continue;
  307.          }
  308.          if(flags.mv) {
  309.             if(multi<COLNO && !--multi)
  310.                flags.mv = flags.run = 0;
  311.             domove();
  312.          } else {
  313.             --multi;
  314.             rhack(save_cm);
  315.          }
  316.         } else if(multi == 0)
  317.             rhack((char *) 0);
  318.         if(multi && multi%7 == 0)
  319.             (void) fflush(stdout);
  320.    }
  321. }
  322.  
  323. lockcheck()
  324. {
  325. /*   extern int errno;                         */
  326. /*   register int i, fd;                       */
  327. /*                                             */
  328. /* we ignore QUIT and INT at this point        */
  329. /*    if (link(perm,safelock) == -1)           */
  330. /*        error("Cannot link safelock. (Try again or rm safelock.)");*/
  331. /*                                             */
  332. /*                                             */
  333. /*    for(i = 0; i < locknum; i++) {           */
  334. /*       lock[0]= 'a' + i;                     */
  335. /*       if((fd = open(lock,0)) == -1) {       */
  336. /*          if(errno == ENOENT) goto gotlock;  */  /* no such file */
  337. /*          (void) unlink(safelock);           */
  338. /*          error("Cannot open %s", lock);    */
  339. /*       }                    */
  340. /*       (void) close(fd);            */
  341. /*    }                        */
  342. /*     (void) unlink(safelock);            */
  343. /*   error("Too many hacks running now.");    */
  344. /*    }                    */
  345. /* gotlock:                    */
  346. /*    fd = creat(lock,FMASK);                  */
  347. /*    if(unlink(safelock) == -1) {        */
  348. /*        error("Cannot unlink safelock.");*/
  349. /*    if(fd == -1) {                           */
  350. /*       error("cannot creat lock file.");     */
  351. /*    } else {                                 */
  352. /*       int pid;                              */
  353. /*                                             */
  354. /*       pid = getpid();                       */ 
  355. /*        if(write(fd, (char *) &pid, sizeof(pid)) != sizeof(pid)){ */
  356. /*          error("cannot write lock");        */
  357. /*       }                                     */
  358. /*    if(close(fd) == -1) {            */
  359. /*          error("cannot close lock");        */
  360. /*       }                                     */
  361. /*    }                                        */
  362. }
  363.  
  364. /*VARARGS1*/
  365. error(s,a1,a2,a3,a4) char *s,*a1,*a2,*a3,*a4;
  366.    {
  367.    myprintf("Error: ");
  368.    myprintf(s,a1,a2,a3,a4);
  369.    (void) myputchar('\n');
  370.    hackexit(1);
  371.    }
  372.  
  373. glo(foo)
  374. register int foo;
  375. {
  376.    /* construct the string  xlock.n  */
  377.    register char *tf;
  378.  
  379.    tf = lock;
  380.    while(*tf && *tf!='.') tf++;
  381.    (void) sprintf(tf, ".%d", foo);
  382. }
  383.  
  384. /*
  385.  * plname is filled either by an option (-u Player  or  -uPlayer) or
  386.  * explicitly (-w implies wizard) or by askname.
  387.  * It may still contain a suffix denoting pl_character.
  388.  */
  389. askname(){
  390. register int c,ct;
  391.    myprintf("\nWho are you? ");
  392.    ct = 0;
  393.    (void) myfflush();
  394.    while((c = inchar()) != '\n')
  395.       {
  396.       if (c != '-')
  397.          if (c == 8) { /* backspace */
  398.             if (ct) {
  399.         ct--;
  400.         backsp();
  401.         myputchar(' ');
  402.         backsp();
  403.         myfflush();
  404.         }
  405.         continue;
  406.             }
  407.          else
  408.             if (c < 'A' || (c > 'Z' && c < 'a') || c > 'z') c = '_';
  409.                if (ct < sizeof(plname)-1)
  410.                   {
  411.                   plname[ct++] = c;
  412.                   myprintf("%c", c);
  413.                   }
  414.     (void) myfflush();
  415.       }
  416.    plname[ct] = 0;
  417.    if(ct == 0) askname();
  418. #ifdef QUEST
  419.    else myprintf("Hello %s, welcome to quest!\n", plname);
  420. #else
  421.    else myprintf("Hello %s, welcome to hack!\n", plname);
  422. #endif QUEST
  423. }
  424.  
  425. impossible(){
  426.    pline("Program in disorder - perhaps you'd better Quit");
  427. }
  428.  
  429. #ifdef NEWS
  430. int stopnews;
  431.  
  432. stopnws(){
  433.    (void) signal(SIGINT, SIG_IGN);
  434.    stopnews++;
  435. }
  436.  
  437. outnews(fd) int fd; {
  438. int (*prevsig)();
  439. char ch;
  440.    prevsig = signal(SIGINT, stopnws);
  441.    while(!stopnews && read(fd,&ch,1) == 1)
  442.       (void) myputchar(ch);
  443.    (void) myputchar('\n');
  444.    (void) myfflush(stdout);
  445.    (void) close(fd);
  446.    (void) signal(SIGINT, prevsig);
  447.    /* See whether we will ask TSKCFW: he might have told us already */
  448.    if(!stopnews && pl_character[0])
  449.       getret();
  450. }
  451. #endif NEWS
  452.  
  453. chdirx(dir) char *dir; {
  454.    if(chdir(dir) < 0) {
  455.       perror(dir);
  456.       error("Cannot chdir to %s.", dir);
  457.    }
  458. }
  459.